package net.nohaven.proj.javeau.fs.crypt;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import net.nohaven.proj.javeau.crypt.prng.PRNG;
import net.nohaven.proj.javeau.crypt.streams.PhelixOutputStream;
import net.nohaven.proj.javeau.fs.model.FSFile;
import net.nohaven.proj.javeau.fs.model.FSFileWriter;

public class CFSFileWriter implements FSFileWriter {
	private File realFile;
	private byte[] key, iv;
	private String name;
	private CFSDirectory parent;
	private Runnable onCommit;
	private PhelixOutputStream stream;

	protected CFSFileWriter(byte[] key, String name, CFSDirectory parent,
			File baseDir, Runnable onCommit) {
		this.key = key;
		this.name = name;
		this.parent = parent;
		this.onCommit = onCommit;

		iv = new byte[5];
		//finds a free IV
		do {
			PRNG.getInstance().getBytes(iv);
			realFile = new File(baseDir, CFSUtils.iv2path(iv));
		} while (realFile.exists());

	}

	public void abort() throws IOException {
		if (!stream.isClosed())
			stream.close();
		realFile.delete();
	}

	public FSFile commit() throws IOException {
		//FIXME during writing, the file doesn't actually exist in the parent
		//CFSDir, so it could be duplicated
		if (!stream.isClosed())
			stream.close();
		FSFile ret = new CFSFile(realFile, name, key, iv, stream.getMac());
		parent.add(ret);
		onCommit.run();
		return ret;
	}

	public OutputStream getOutputStream() {
		try {
			OutputStream fos = new FileOutputStream(realFile, false);
			stream = new PhelixOutputStream(fos, key, iv, true);
			return stream;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
}
